/****************************************Copyright (c)****************************************************
**                                       fhqlongteng@163.com                              
**                                       QQ:283669063
**--------------File Info---------------------------------------------------------------------------------
** File name:           zFTP.c
** Last modified Date:  2024-6-14
** Last Editors:        wjw 3358953076@qq.com
** Description:         增加接收缓存,以应对欢迎消息过长导致TCP粘包；更改文件下载接口，解决服务器不返回文件大小导致下载失败
** Last Version:        V1.10
** Descriptions:        ZFTP协议实现程序
**
**--------------------------------------------------------------------------------------------------------
** Created by:          Zhao shimin
** Created date:        2020-12-01
** Version:             V1.00
** Descriptions:
**
**
**--------------------------------------------------------------------------------------------------------
** Modified by:         
** Modified date:       
** Version:             
** Descriptions:        
**
** Rechecked by:
*********************************************************************************************************/
#include <rtthread.h>
#include <rtdevice.h>
#include "zFTP.h"
//#include <fal.h>


#ifdef PKG_USING_ZFTP

#define DBG_TAG "zFTP_DEMO"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

/*********************************************************************************************************
*  　　　　　　定义FTP的默认用户名称，服务器地址，端口等
*********************************************************************************************************/
#define FTP_SVR_ADDR    "服务器url"
#define FTP_SVR_PATH    "21"
#define FTP_USER_NAME   "用户名"
#define FTP_PASSWORD    "密码"
//#define FTP_FILENAME    "文件地址"
//#define FIRMWARE_FLASH_PARTITION  "sf"
//#define FIRMWARE_STORE_ADDR        0


/*********************************************************************************************************
** Function name：      file_read()
** Descriptions:        read file from flash 
** input parameters：   ftp, buf, len, file_pos, total_len
** output parameters：  None
** Returned value:      RT_OK, RT_ERROR
*********************************************************************************************************/
int file_read(void * handle, char *file_name, rt_uint8_t *buf, rt_uint32_t len, rt_uint32_t file_pos, rt_uint32_t *read_len, rt_uint32_t *total_len)
{
#if 0
    const struct fal_partition *partition = RT_NULL;

    LOG_I("file_read:%s %d %d %d",file_name,file_pos,*read_len,*total_len);
    for(int i= 0;i<len;i++){
        rt_kprintf("%c",buf[i]);
    }
    rt_kprintf("\n");

    *total_len = 600 * 1024;

    partition = fal_partition_find(FIRMWARE_FLASH_PARTITION);
    if (partition == RT_NULL)
    {
        LOG_E("Find partition (%s) failed, Cannot save the net para!", FIRMWARE_FLASH_PARTITION);
        return -RT_ERROR;  
    }

    if(file_pos + len <= *total_len)
    {
        *read_len = len;
    }
    else
    {
        *read_len = *total_len - file_pos;
    }

    if(*read_len != fal_partition_read(partition, FIRMWARE_STORE_ADDR + file_pos, buf, *read_len))
    {
        LOG_E("write file error, file_pos = %d", file_pos); 
    }
#endif

    return RT_EOK;


}     



/*********************************************************************************************************
** Function name：      file_write()
** Descriptions:        write file into flash 
** input parameters：   ftp, buf, len, file_pos, total_len
** output parameters：  None
** Returned value:      RT_OK, RT_ERROR
*********************************************************************************************************/
int file_write(void * handle, char *file_name, rt_uint8_t *buf, rt_uint32_t len, rt_uint32_t file_pos, rt_uint32_t total_len)
{
    LOG_I("file_write:%s %d %d",file_name,file_pos,total_len);
    LOG_I("packet[%d]:",len);
    for(int i= 0;i<len;i++){
        rt_kprintf("%.2X ",buf[i]);
    }
    rt_kprintf("\n");
#if 0
    const struct fal_partition *partition = RT_NULL;
    partition = fal_partition_find(FIRMWARE_FLASH_PARTITION);
    if (partition == RT_NULL)
    {
        LOG_E("Find partition (%s) failed, Cannot save the net para!", FIRMWARE_FLASH_PARTITION);
        return -RT_ERROR;  
    }

    if(len != fal_partition_write(partition, FIRMWARE_STORE_ADDR + file_pos, buf, len))
    {
        LOG_E("write file error, file_pos = %d", file_pos); 
    }

#endif
    return RT_EOK;


}

/*********************************************************************************************************
** Function name：      file_write()
** Descriptions:        write file into flash 
** input parameters：   ftp, buf, len, file_pos, total_len
** output parameters：  None
** Returned value:      RT_OK, RT_ERROR
*********************************************************************************************************/
int file_erase(rt_uint32_t file_len)
{
#if 0
    const struct fal_partition *partition = RT_NULL;

    partition = fal_partition_find(FIRMWARE_FLASH_PARTITION);
    if (partition == RT_NULL)
    {
        LOG_E("Find partition (%s) failed, Cannot save the net para!", FIRMWARE_FLASH_PARTITION);
        return -RT_ERROR;  
    }

    if(file_len != fal_partition_erase(partition, FIRMWARE_STORE_ADDR, file_len))
    {
        LOG_E("erase flash error"); 
    }

#endif
    return RT_EOK;
}


/*********************************************************************************************************
** Function name：      cmd_ftp_download()
** Descriptions:        ftp download command line
** input parameters：   argc, argv
** output parameters：  None
** Returned value:      RT_OK, RT_ERROR
*********************************************************************************************************/
int cmd_ftp_download(int argc, char **argv)
{
    zftp_client *ftp;
    rt_uint32_t file_size = 0;

    
    
    ftp = zFTP_login(FTP_USER_NAME, FTP_PASSWORD, FTP_SVR_ADDR);

    if(ftp == RT_NULL)
    {
        rt_kprintf("zFTP login fail!\n");
    } 
    else
    {
        LOG_I("zFTP_set_callback");
        zFTP_set_callback(ftp, file_write, file_read, RT_NULL);
        LOG_I("zFTP_change_path");
        zFTP_change_path(ftp, FTP_SVR_PATH);

        if(rt_strcmp(argv[2], "upload") == 0)
        {
            LOG_I("zFTP_upload_file");
            if(RT_EOK == zFTP_upload_file(ftp, argv[1]))
            {
                rt_kprintf("zFTP upload success!\n");
            }
            else
            {
                rt_kprintf("zFTP upload  %s faile!\n", argv[1]);
            }  
        }
        else
        {
            LOG_I("zFTP_get_filesize");
            if(RT_EOK == zFTP_get_filesize(ftp, argv[1], &file_size))
            {
              rt_kprintf("zFTP file %s size:%d!\n", argv[1], file_size);
              file_erase(file_size);
              LOG_I("zFTP_download_file");
              if(RT_EOK == zFTP_download_file(ftp, argv[1],file_size))
              {
                  rt_kprintf("zFTP download success len: %d!\n", file_size);
              }
                    
            }
        }
        
        zFTP_quit(ftp);

    }  
    
    return 0;
}

#ifdef FINSH_USING_MSH
#include <finsh.h>
MSH_CMD_EXPORT_ALIAS(cmd_ftp_download ,ftp,  ftp download file);
#endif


/*********************************************************************************************************
**   End of file
*********************************************************************************************************/
#endif

